import { Component, OnInit, ViewChild } from '@angular/core'
import { combineLatest } from 'rxjs'
import { take } from 'rxjs/operators'
import { NzTreeComponent, NzTreeNode } from 'ng-zorro-antd'
import { ArrayService } from '@delon/util'

import { DataService } from '@shared/services/data.service'
import { RoleDataService } from '../../role-data.service'
import { TreeService } from '@shared/services/tree.service'
import { NewPageAccessor } from '@shared/components/new-page/new-page.interface'
import { IRoleCreateFormData } from '@shared/interfaces/role'

@Component({
  selector: 'app-role-new-functions',
  templateUrl: './role-new-functions.component.html',
  styleUrls: ['./role-new-functions.component.less'],
})
export class RoleNewFunctionsComponent implements NewPageAccessor, OnInit {
  constructor(
    private roleDataService: RoleDataService,
    private dataService: DataService,
    private treeService: TreeService,
    private arrayService: ArrayService,
  ) {}

  @ViewChild('tree') tree: NzTreeComponent

  data: any
  payload?: any
  isLoading = false
  isExpandAll = false
  nodes: NzTreeNode[]
  checkedKeys: string[] = []

  ngOnInit() {
    this.isLoading = true
    combineLatest(this.roleDataService.menuTree$, this.dataService.roleCreateData$.value$)
      .pipe(take(1))
      .subscribe(value => {
        const [tree, formData] = value
        this.nodes = tree
        this.isLoading = false

        const tempMap = new Map<number, number>()
        const functions = formData.functions || []
        for (const id of functions) {
          tempMap.set(id, id)
        }

        const checkedKeys: string[] = this.arrayService
          .treeToArr(tree)
          .filter(node => tempMap.has(node.origin.menuId))
          .map(node => node.key)
        this.checkedKeys = checkedKeys
      })
  }

  computeResult(): IRoleCreateFormData {
    const role = this.dataService.roleCreateData$.value
    const fun: Map<number, number> = new Map()

    const nodes = this.tree.getCheckedNodeList()
    const result = this.treeService.dfs(nodes)
    for (const f of result) {
      fun.set(f, f)
    }
    role.functions = Array.from(fun.keys())

    return role
  }

  checkValid(): boolean {
    this.pushDataToStore()
    return true
  }

  pushDataToStore(): void {
    this.payload = this.computeResult()
  }
}
